qt 您所在的位置:网站首页 qt Mac窗口最小化 qt

qt

2024-02-27 09:39| 来源: 网络整理| 查看: 265

我有一个 Window在我的项目中创建子类,并在运行时创建实例并完全在 QML 端显示。我知道我可以通过不包含 WindowMinimizeButtonHint 来防止窗口最小化。在 flags: ,但我实际上需要存在并启用最小化按钮,但能够拦截最小化按钮点击,取消实际最小化,并做其他事情(仅供引用,我的客户需要这种非标准的窗口行为,而不是我)。

到目前为止,我唯一能做到的就是处理 onWindowStateChanged:事件,检查是否 windowState === Qt.WindowStateMinimized并调用 show()来自计时器(在事件处理程序中直接调用它什么都不做)。这会导致窗口向下移动到系统托盘,然后突然恢复正常。

有什么办法可以做到这一点,比如 OnMinimized可以取消的事件?

编辑:基于 Benjamin T 的回答,我至少是 OSX 解决方案的一部分:

#import bool NativeFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) { if (eventType == "mac_generic_NSEvent") { NSEvent *event = static_cast(message); if ([event type] == NSKeyDown) { return true; } } return false; } 在这个例子中,我能够拦截和取消所有 NSKeyDown 事件(同时让鼠标点击等其他事件仍然有效)。剩下的问题是我还是不知道拦截一个最小化事件 - NSEvent.h 似乎没有任何内容。也许我需要转换到不同类型的事件?

编辑 2 - 工作解决方案:

我无法找到任何方法来正确拦截最小化事件并取消它,所以我的解决方法是拦截窗口上的点击,确定点击是否超过最小化按钮(或关闭或缩放按钮)并取消事件如果是这样(并向我的 qml 窗口发送一个点击发生的通知)。我还处理了双击标题栏缩放窗口,并使用 Command-M 键最小化窗口的情况。

第一步是实现 QAbstractNativeEventFilter .在您的标题中:

#include class NativeFilter : public QAbstractNativeEventFilter { public: bool nativeEventFilter(const QByteArray &eventType, void *message, long *result); }; 实现:#import #import #import bool NativeFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) { if (eventType == "mac_generic_NSEvent") { NSEvent *event = static_cast(message); NSWindow *win = [event window]; // TODO: determine whether or not this is a window whose // events you want to intercept. I did this by checking // [win title] but you may want to find and use the // window's id instead. // Detect a double-click on the titlebar. If the zoom button // is enabled, send the full-screen message to the window if ([event type] == NSLeftMouseUp) { if ([event clickCount] > 1) { NSPoint pt = [event locationInWindow]; CGRect rect = [win frame]; // event coordinates have y going in the opposite direction from frame coordinates, very annoying CGFloat yInverted = rect.size.height - pt.y; if (yInverted = rectButton.origin.y) && (yInverted = rectButton.origin.x) && (pt.x = rectButton.origin.y) && (yInverted = rectButton.origin.x) && (pt.x = rectButton.origin.y) && (yInverted = rectButton.origin.x) && (pt.x installEventFilter(new EventFilter()); return app.exec(); } class EventFilter : public QObject { Q_OBJECT public: explicit EventFilter(QObject *parent = nullptr); bool eventFilter(QObject *watched, QEvent *event) override; }; bool EventFilter::eventFilter(QObject *watched, QEvent *event) { if (event->type() == QEvent::WindowStateChange) { auto e = static_cast(event); auto window = static_cast(watched); if (window->windowStates().testFlag(Qt::WindowMinimized) && ! e->oldState().testFlag(Qt::WindowMinimized)) { // Restore old state window->setWindowStates(e->oldState()); return true; } } // Do not filter event return false; } 但是,您很快就会遇到与使用信号/槽机制时相同的问题:Qt 仅在窗口已经最小化时通知您。这意味着此时恢复窗口将产生隐藏/显示效果。

因此,您需要更深入地了解 native 事件过滤器。

以下代码适用于 Windows,您应该针对 macOS 进行调整:

class NativeFilter : public QAbstractNativeEventFilter { public: bool nativeEventFilter(const QByteArray &eventType, void *message, long *result); }; bool NativeFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) { /* On Windows we interceot the click in the title bar. */ /* If we wait for the minimize event, it is already too late. */ #ifdef Q_OS_WIN auto msg = static_cast(message); // Filter out the event when the minimize button is pressed. if (msg->message == WM_NCLBUTTONDOWN && msg->wParam == HTREDUCE) return true; #endif /* Example macOS code from Qt doc, adapt to your need */ #ifdef Q_OS_MACOS if (eventType == "mac_generic_NSEvent") { NSEvent *event = static_cast(message); if ([event type] == NSKeyDown) { // Handle key event qDebug()


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有